package com.puboot.module.blog.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.puboot.common.shiro.MyShiroRealm;
import com.puboot.common.util.*;
import com.puboot.exception.ArticleNotFoundException;
import com.puboot.fileservice.FileService;
import com.puboot.module.admin.model.BizArticle;
import com.puboot.module.admin.model.BizCategory;
import com.puboot.module.admin.model.User;
import com.puboot.module.admin.service.BizArticleService;
import com.puboot.module.admin.service.BizCategoryService;
import com.puboot.module.admin.service.BizThemeService;
import com.puboot.module.admin.service.UserService;
import com.puboot.module.admin.vo.ArticleConditionVo;
import com.puboot.module.admin.vo.ChangePasswordVo;
import com.puboot.module.admin.vo.base.ResponseVo;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * CMS页面相关接口
 *
 * @author Jasper Huang
 * @version V1.0
 * @date 2020年08月10日
 */
@Controller
@AllArgsConstructor
public class BlogWebController {

    private static final String THEME_PREFIX = "theme/";

    private final BizArticleService bizArticleService;
    private final BizCategoryService categoryService;
    private final BizThemeService bizThemeService;

    private final FileService fileService;

    private final UserService userService;
    private final MyShiroRealm shiroRealm;
    /**
     * 首页
     *
     * @param model
     * @param vo
     * @return
     */
    @GetMapping("/")
    public String index(Model model, ArticleConditionVo vo) {
        model.addAttribute("pageUrl", "blog/index");
        model.addAttribute("categoryId", "index");
        model.addAttribute("sliderList", bizArticleService.sliderList());//轮播文章
        loadMainPage(model, vo);
        return THEME_PREFIX + bizThemeService.selectCurrent().getName() + "/index";
    }

    /**
     * 文章列表分页
     *
     * @param pageNumber
     * @param vo
     * @param model
     * @return
     */
    @RequestMapping("/blog/index/{pageNumber}")
    public String index(@PathVariable("pageNumber") Integer pageNumber, ArticleConditionVo vo, Model model) {
        vo.setPageNumber(pageNumber);
        model.addAttribute("pageUrl", "blog/index");
        model.addAttribute("categoryId", "index");
        loadMainPage(model, vo);
        return THEME_PREFIX + bizThemeService.selectCurrent().getName() + "/index";
    }

    /**
     * 分类列表
     *
     * @param categoryId
     * @param model
     * @return
     */
    @GetMapping("/blog/category/{categoryId}")
    public String category(@PathVariable("categoryId") Integer categoryId, Model model) {
        ArticleConditionVo vo = new ArticleConditionVo();
        vo.setCategoryId(categoryId);
        model.addAttribute("pageUrl", "blog/category/" + categoryId);
        model.addAttribute("categoryId", categoryId);
        loadMainPage(model, vo);
        return THEME_PREFIX + bizThemeService.selectCurrent().getName() + "/index";
    }

    @GetMapping("/blog/category/{categoryId}/{pageNumber}")
    public String category(@PathVariable("categoryId") Integer categoryId, @PathVariable("pageNumber") Integer pageNumber, Model model) {
        ArticleConditionVo vo = new ArticleConditionVo();
        vo.setCategoryId(categoryId);
        vo.setPageNumber(pageNumber);
        model.addAttribute("pageUrl", "blog/category/" + categoryId);
        model.addAttribute("categoryId", categoryId);
        loadMainPage(model, vo);
        return THEME_PREFIX + bizThemeService.selectCurrent().getName() + "/index";
    }


    /**
     * 标签列表
     *
     * @param tagId
     * @param model
     * @return
     */
    @GetMapping("/blog/tag/{tagId}")
    public String tag(@PathVariable("tagId") Integer tagId, Model model) {
        ArticleConditionVo vo = new ArticleConditionVo();
        vo.setTagId(tagId);
        model.addAttribute("pageUrl", "blog/tag/" + tagId);
        loadMainPage(model, vo);
        return THEME_PREFIX + bizThemeService.selectCurrent().getName() + "/index";
    }

    /**
     * 标签列表（分页）
     *
     * @param tagId
     * @param pageNumber
     * @param model
     * @return
     */
    @GetMapping("/blog/tag/{tagId}/{pageNumber}")
    public String tag(@PathVariable("tagId") Integer tagId, @PathVariable("pageNumber") Integer pageNumber, Model model) {
        ArticleConditionVo vo = new ArticleConditionVo();
        vo.setTagId(tagId);
        vo.setPageNumber(pageNumber);
        model.addAttribute("pageUrl", "blog/tag/" + tagId);
        loadMainPage(model, vo);
        return THEME_PREFIX + bizThemeService.selectCurrent().getName() + "/index";
    }

    /**
     * 文章详情
     *
     * @param model
     * @param articleId
     * @return
     */
    @GetMapping("/blog/article/{articleId}")
    public String article(HttpServletRequest request, Model model, @PathVariable("articleId") Integer articleId) {
        BizArticle article = bizArticleService.selectById(articleId);
        if (article == null || CoreConst.STATUS_INVALID.equals(article.getStatus())) {
            throw new ArticleNotFoundException();
        }
        model.addAttribute("article", article);
        model.addAttribute("categoryId", article.getCategoryId());
        return THEME_PREFIX + bizThemeService.selectCurrent().getName() + "/article";
    }

    /**
     * 评论
     *
     * @param model
     * @return
     */
    @GetMapping("/blog/comment")
    public String comment(Model model) {
        model.addAttribute("categoryId", "comment");
        return THEME_PREFIX + bizThemeService.selectCurrent().getName() + "/comment";
    }

    private void loadMainPage(Model model, ArticleConditionVo vo) {
        vo.setStatus(CoreConst.STATUS_VALID);
        IPage<BizArticle> page = new Pagination<>(vo.getPageNumber(), vo.getPageSize());
        List<BizArticle> articleList = bizArticleService.findByCondition(page, vo);
        model.addAttribute("page", page);
        model.addAttribute("articleList", articleList);//文章列表
        if (vo.getCategoryId() != null) {
            BizCategory category = categoryService.getById(vo.getCategoryId());
            if (category != null) {
                model.addAttribute("categoryName", category.getName());
            }
        }
    }


     @RequestMapping("/blog/search/{pageNumber}")
    public String get(Model model,@RequestParam(name = "keyword") String keyword, @RequestParam(name = "path") String path,
                      @PathVariable("pageNumber") Integer pageNumber, ArticleConditionVo vo,
                      @RequestParam(name = "es_size", defaultValue = "10") Integer esSize) throws IOException {
        List<Map> list = new ArrayList<>();
        boolean pageSetUp = false;
        try {
            if (StringUtils.isNotEmpty(keyword)) {
                list = fileService.queryFileFromES("esfile", keyword, path, (pageNumber-1)*esSize, esSize);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
         model.addAttribute("pageUrl", "blog/search");
         model.addAttribute("categoryId", "index");

         Map<String, String> bizCategoriesMap = categoryService.selectAll();


         vo.setStatus(CoreConst.STATUS_VALID);
         IPage<BizArticle> page = new Pagination<>(vo.getPageNumber(), vo.getPageSize());

//         List<BizArticle> articleList = bizArticleService.findByCondition(page, vo);
            List<BizArticle> articleList = new ArrayList<BizArticle>();
            for(Map detail:list){
                if(!pageSetUp){
                    page.setTotal(Long.parseLong(detail.get("totaRecords").toString().replace("hits","")
                    .replace("hit","").trim()
                    ));
                }
                BizArticle bizArticle = JSONObject.toJavaObject(JSONObject.parseObject(detail.get("path").toString()),BizArticle.class)  ;
                //这里需要判断因为有多个关键词加入搜索
                Object text = detail.get("text");
                Object titleName = detail.get("name");
                if(text!=null&&StringUtils.isNotBlank(text.toString())){
                    bizArticle.setContent(text.toString());
                }
                if(titleName!=null&&StringUtils.isNotBlank(titleName.toString())){
                    bizArticle.setTitle(titleName.toString());
                }

                BizCategory bizCategory = new BizCategory();
                Integer categoryId = bizArticle.getCategoryId();
                if(bizArticle.getCategoryId()!=null){
                    String cateId = categoryId.toString();
                    String name = bizCategoriesMap.get(cateId);
                    bizCategory.setName(name);
                    bizCategory.setId(categoryId);
                }
                bizArticle.setBizCategory(bizCategory);
                articleList.add(bizArticle);
            }
         page.setCurrent(vo.getPageNumber());

         model.addAttribute("page", page);
         model.addAttribute("articleList", articleList);//文章列表

         model.addAttribute("keyword",keyword);
         return THEME_PREFIX + bizThemeService.selectCurrent().getName() + "/searchindex";
    }

    /**
     * 编辑用户详情
     */
    @GetMapping("/blog/user/edit")
    public String userDetail(Model model) {
        User loginUser = userService.selectByUserId(((User) SecurityUtils.getSubject().getPrincipal()).getUserId());
        model.addAttribute("user", loginUser);
        return CoreConst.ADMIN_PREFIX + "user/form";
    }


    /**
     * 编辑用户
     */
    @PostMapping("/blog/user/infoedit")
    @ResponseBody
    public ResponseVo editUser(User userForm, String confirmPassword) {

        String password = userForm.getPassword();
        //判断两次输入密码是否相等
        if (confirmPassword != null && password != null) {
            if (!confirmPassword.equals(password)) {
                return ResultUtil.error("两次密码不一致");
            }
        }
        userForm.setUserId(((User) SecurityUtils.getSubject().getPrincipal()).getUserId());
        PasswordHelper.encryptPassword(userForm);
        int a = userService.updateByUserId(userForm);
        if (a > 0) {
            return ResultUtil.success("编辑用户成功！");
        } else {
            return ResultUtil.error("编辑用户失败");
        }
    }

    /*修改密码*/
    @RequestMapping(value = "/blog/changePassword", method = RequestMethod.POST)
    @ResponseBody
    public ResponseVo changePassword(ChangePasswordVo changePasswordVo) {
        if (!changePasswordVo.getNewPassword().equals(changePasswordVo.getConfirmNewPassword())) {
            return ResultUtil.error("两次密码输入不一致");
        }
        User loginUser = userService.selectByUserId(((User) SecurityUtils.getSubject().getPrincipal()).getUserId());
        User newUser = CopyUtil.getCopy(loginUser, User.class);
        String sysOldPassword = loginUser.getPassword();
        newUser.setPassword(changePasswordVo.getOldPassword());
        String entryOldPassword = PasswordHelper.getPassword(newUser);
        if (sysOldPassword.equals(entryOldPassword)) {
            newUser.setPassword(changePasswordVo.getNewPassword());
            PasswordHelper.encryptPassword(newUser);
            userService.updateById(newUser);
            //*清除登录缓存*//
            List<String> userIds = new ArrayList<>();
            userIds.add(loginUser.getUserId());
            shiroRealm.removeCachedAuthenticationInfo(userIds);
            /*SecurityUtils.getSubject().logout();*/
        } else {
            return ResultUtil.error("您输入的旧密码有误");
        }
        return ResultUtil.success("修改密码成功");
    }

}
